#pragma once

#include<iostream>
#include<string>
#include<vector>
#include<sstream> //字符串转化为流
#include<map>
#include<fstream>
#include<unordered_map>

const static std::string base_sep = "\r\n";
const static std::string line_sep = ": ";
const static std::string prefixpath = "wwwroot"; //web根目录
const static std::string homepage = "index.html"; //web根目录
const static std::string httpversion = "HTTP/1.0";
const static std::string spacesep = " ";

class HttpRequest
{
private:
    std::string Getline(std::string &reqstr)
    {
        auto pos = reqstr.find(base_sep);
        if(pos == std::string::npos) return std::string();  //有可能返回空
        std::string line = reqstr.substr(0, pos);
        reqstr.erase(0, line.size() + base_sep.size());
        return line.empty() ? base_sep : line;
    }
public:
    HttpRequest()
        :_blank_line(base_sep)
        ,_path(prefixpath)
    {}

    void Deserialize(std::string &reqstr) // 反序列化:  字符串-->结构化字段
    {
        _req_line = Getline(reqstr);
        std::string header;
        do
        {
            header = Getline(reqstr);
            if(header.empty()) break;
            else if(header == base_sep) break;
            _req_headers.push_back(header);

        } while(true);
        
        if(!reqstr.empty()) _body_text = reqstr;

        //进一步反序列化
        ParseReqline();
        ParseReqHeader();
    }
    //在继续反序列化

    void ParseReqline()
    {
        std::stringstream ss(_req_line); //按空格分割 cin >>
        ss >> _method >> _url >> _version;

        _path +=_url;
        if(_path[_path.size() - 1] == '/')
            _path += homepage;
    }

    void ParseReqHeader()
    {
        for(auto &header : _req_headers)
        {
            auto pos = header.find(line_sep);
            if(pos == std::string::npos) continue;
            std::string k = header.substr(0, pos);
            std::string v = header.substr(pos + line_sep.size());
            if(k.empty() || v.empty()) continue;

            _headers_kv.insert(std::make_pair(k, v));
        } 
    }

    std::string Url()
    {
        LOG(DEBUG, "Client want url %s\n", _url.c_str());
        return _url;
    }
    std::string Path()
    {
        LOG(DEBUG, "Client want path %s\n", _path.c_str());
        return _path;

    }
    void Print()
    {
        std::cout << "###" << _req_line << std::endl;
        for(auto &header: _req_headers)
        {
            std::cout << "@@@" << header << std::endl;
        }
        std::cout << "***" << _blank_line;
        std::cout << "method:" << _method << std::endl;
        std::cout << "url:" << _url << std::endl;
        std::cout << "version:" << _version << std::endl;

        for(auto &header_kv : _headers_kv)
        {
            std::cout << ")))" << header_kv.first << "-->" << header_kv.second << std::endl;
        }
    }

    ~HttpRequest()
    {}
private:
    //基本的httprequest格式
    std::string _req_line;     //请求行   --->  请求方法 空格 URL 空格 HTTPversion base_sep
    std::vector<std::string> _req_headers; // 报头
    std::string _blank_line;   //空行     ---> 空行只有一个换行符 正好终止while循环
    std::string _body_text;     //正文

    
    //更具体的属性字段
    std::string _method;
    std::string _url;
    std::string _path;
    std::string _version;
    std::unordered_map<std::string, std::string> _headers_kv;
};

class HttpResponse
{
public:
    HttpResponse()
        :_version(httpversion)
        ,_blank_line(base_sep)
    {}

    void AddCode(int code)
    {
        _status_code = code;
        _desc = "OK";
    }
    void AddHeader(const std::string &k, const std::string &v)
    {
        _headers_kv[k] = v;
    }
    void AddBodyText(const std::string &body_text)
    {
        _resp_body_text = body_text;
    }
    ~HttpResponse()
    {}
    std::string Serialize() // 序列化  : 结构化字段-->字符串
    {
        //1.构建状态行
        _status_line = _version + spacesep + std::to_string(_status_code) + spacesep + _desc + base_sep;

        //2.构建应答报头
        for(auto &header : _headers_kv)
        {
            std::string header_line = header.first + line_sep + header.second + base_sep;
            _resp_headers.push_back(header_line);
        }
        //3.空行和正文

        //4.正式序列化
        std::string responsestr = _status_line;
        for(auto &line : _resp_headers)
        {
            responsestr += line;
        }
        responsestr += _blank_line;
        responsestr += _resp_body_text;
        
        return responsestr;
    }
private:
    //基本属性
    std::string _version;
    int _status_code;
    std::string _desc;  //状态码描述
    std::unordered_map<std::string, std::string> _headers_kv;
    //基本的httpresponse格式
    std::string _status_line; //状态行
    std::vector<std::string> _resp_headers; //响应报头
    std::string _blank_line;        //空行
    std::string _resp_body_text;    //响应正文

};

class HttpSever
{
private:
    std::string GetFileContent(const std::string &path)
    {
        std::ifstream in(path, std::ios::binary);
        if (!in.is_open())
            return std::string();
        in.seekg(0, in.end);
        int filesize = in.tellg(); // 告知我你的rw偏移量是多少
        in.seekg(0, in.beg);

        std::string content;
        content.resize(filesize);
        in.read((char *)content.c_str(), filesize);
        in.close();

        return content;
    }

public:
    HttpSever()
    {}
    std::string HandlerHttpRequest(std::string &reqstr)
    {
#ifdef TEST
        std::cout << "------------------" << std::endl;
        std::cout << reqstr;

        std::string responsestr = "HTTP/1.1 200 OK\r\n";
        responsestr += "Content-Type:text/html\r\n";
        responsestr += "\r\n";
        responsestr += "<html><h1>hello lty!</h1></html>";

        return responsestr;
#else
        HttpRequest req;
        req.Deserialize(reqstr);

        std::string content = GetFileContent(req.Path());
        if(content.empty()) return std::string(); //TODO


        HttpResponse resp;
        
        resp.AddCode(200);
        resp.AddHeader("Content-Length", std::to_string( content.size() ) );
        resp.AddBodyText(content);

        return resp.Serialize();
#endif
    }
    ~HttpSever()
    {}
}; 